/*
 *  SyncIT , easy synchronization of files between computers and devices.
 *  Copyright (C) 2011  Christian Masus <cmasus(at)gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version. If redistributing and/or modifying
 *  this file, this notice must be included in the redistributed or
 *  modified copy.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package gui.javagui;

import java.awt.BorderLayout;

import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;

import log.LogInterface;
import log.LogRestrictions;
import log.ReceiveLogInterface;

@SuppressWarnings("serial")
public class TabLoggerPanel extends JPanel implements ReceiveLogInterface {

	private final String LOG_REG_NAME = "javaguilog";

	private JTextArea textArea;
	private JScrollBar scrollBar;
	private int maxVisibleLines;
	private int removeLines;

	public TabLoggerPanel(LogInterface log) {
		setMaxLines(10000);
		setLayout(new BorderLayout());

		textArea = new JTextArea();
		textArea.setEditable(false);
		textArea.setLineWrap(false);

		JScrollPane scrollPane = new JScrollPane(textArea,
				JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

		scrollBar = scrollPane.getVerticalScrollBar();

		add(scrollPane, BorderLayout.CENTER);

		initiateLogging(log);
	}

	/**
	 * Sets maximum numbers of log lines that are shown in the text are.
	 * Also sets how many lines that will be removed every time the text
	 * area reaches its max. Removed lines are a tenth of max lines.
	 * @param maxVisibleLines maximum number of lines in the text area.
	 */
	private void setMaxLines(int maxVisibleLines) {
		this.maxVisibleLines = maxVisibleLines;
		int tenth = maxVisibleLines / 10;
		int remainder = maxVisibleLines % 10;
		if(remainder == 0) {
			removeLines =  tenth;
		}
		else {
			removeLines =  tenth + 1;
		}
	}

	/**
	 * Initiates the functionality so that the text area receives log lines from the
	 * logger part of this application.
	 * @param log reference to the logger.
	 */
	private void initiateLogging(LogInterface log) {
		LogRestrictions restrictions = new LogRestrictions((ReceiveLogInterface)this);
		// TODO add more log restrictions
		log.registerLogReceivers(LOG_REG_NAME, restrictions);
		log.askForLogHistory(LOG_REG_NAME);
		log.subscribeOnLog(LOG_REG_NAME);
	}


	/**
	 * Adds a log line to the text area and removes old lines if necessary.
	 * @param logText the log line.
	 */
	public void logText(String logText) {
		if(textArea.getLineCount() > maxVisibleLines) {
			try {
				textArea.replaceRange("", textArea.getLineStartOffset(0), textArea.getLineStartOffset(removeLines));
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
		}
		boolean autoScroll = false;
		if(scrollBar.getValue() == (scrollBar.getMaximum() - scrollBar.getVisibleAmount())) {
			autoScroll = true;
		}
		textArea.append(logText);
		if(autoScroll) {
			textArea.setCaretPosition(textArea.getDocument().getLength());
		}
	}



	// ReceiveLogInterface //

	public void sendLogLine(String line) {
		logText(line);
	}

}
